feat: Support dynamic image repositories#141
Conversation
| stackable_operator::utils::yaml_from_str_singleton_map(indoc::indoc! {r#" | ||
| - image: | ||
| productVersion: 3.4.0 | ||
| pullPolicy: IfNotPresent | ||
| clusterOperation: | ||
| reconciliationPaused: false | ||
| stopped: false | ||
| clusterConfig: | ||
| keystore: | ||
| - key: s3.client.default.access_key | ||
| secretKeyRef: | ||
| name: s3-credentials | ||
| key: ACCESS_KEY | ||
| - key: s3.client.default.secret_key | ||
| secretKeyRef: | ||
| name: s3-credentials | ||
| key: SECRET_KEY | ||
| security: | ||
| enabled: true | ||
| managingRoleGroup: security-coord | ||
| settings: | ||
| config: | ||
| managedBy: operator | ||
| content: | ||
| value: | ||
| _meta: | ||
| type: config | ||
| config_version: 2 | ||
| config: | ||
| dynamic: | ||
| authc: | ||
| basic_internal_auth_domain: | ||
| description: Authenticate via HTTP Basic against internal users database | ||
| http_enabled: true | ||
| transport_enabled: true | ||
| order: 1 | ||
| http_authenticator: | ||
| type: basic | ||
| challenge: true | ||
| authentication_backend: | ||
| type: intern | ||
| authz: {} | ||
| internalUsers: | ||
| managedBy: API | ||
| content: | ||
| valueFrom: | ||
| secretKeyRef: | ||
| name: opensearch-security-config | ||
| key: internal_users.yml | ||
| roles: | ||
| managedBy: API | ||
| content: | ||
| valueFrom: | ||
| configMapKeyRef: | ||
| name: opensearch-security-config | ||
| key: roles.yml | ||
| rolesMapping: | ||
| managedBy: API | ||
| content: | ||
| value: | ||
| _meta: | ||
| type: rolesmapping | ||
| config_version: 2 | ||
| all_access: | ||
| reserved: false | ||
| backend_roles: | ||
| - admin | ||
| tls: | ||
| serverSecretClass: tls | ||
| internalSecretClass: tls | ||
| vectorAggregatorConfigMapName: vector-aggregator-discovery | ||
| nodes: | ||
| config: | ||
| logging: | ||
| enableVectorAgent: true | ||
| gracefulShutdownTimeout: 2m | ||
| requestedSecretLifetime: 1d | ||
| envOverrides: | ||
| DISABLE_INSTALL_DEMO_CONFIG: "true" | ||
| OPENSEARCH_HOME: /stackable/opensearch | ||
| configOverrides: | ||
| opensearch.yml: | ||
| jsonMergePatch: | ||
| node.store.allow_mmap: false | ||
| cluster.routing.allocation.disk.threshold_enabled: false | ||
| roleConfig: | ||
| discoveryServiceListenerClass: external-unstable | ||
| roleGroups: | ||
| cluster-manager: | ||
| config: | ||
| discoveryServiceExposed: true | ||
| nodeRoles: | ||
| - cluster_manager | ||
| resources: | ||
| storage: | ||
| data: | ||
| capacity: 100Mi | ||
| replicas: 3 | ||
| data: | ||
| config: | ||
| discoveryServiceExposed: false | ||
| nodeRoles: | ||
| - ingest | ||
| - data | ||
| - remote_cluster_client | ||
| listenerClass: cluster-internal | ||
| resources: | ||
| storage: | ||
| data: | ||
| capacity: 2Gi | ||
| configOverrides: | ||
| opensearch.yml: | ||
| jsonMergePatch: | ||
| node.attr.zone: eu-central-1a | ||
| envOverrides: | ||
| OPENSEARCH_JAVA_OPTS: -Xms1g -Xmx1g | ||
| replicas: 2 | ||
| - image: | ||
| custom: oci.example.com/namespace/opensearch:3.4.0-custom | ||
| productVersion: 3.4.0 | ||
| pullPolicy: Always | ||
| pullSecrets: | ||
| - name: registry-credentials | ||
| clusterConfig: | ||
| tls: | ||
| serverSecretClass: null | ||
| security: | ||
| enabled: false | ||
| nodes: | ||
| roleGroups: | ||
| default: | ||
| replicas: 1 | ||
| "#}) | ||
| .expect("Failed to parse OpenSearchClusterSpec YAML") |
There was a problem hiding this comment.
I used json! instead of indoc! in this operator. One advantage is that the compiler supports you to write valid specs. If you change the operator and try to insert parts into this huge YAML string, it is sometimes hard to get the indentation right.
But I do not insist on using json!.
In case, you want to apply it:
| stackable_operator::utils::yaml_from_str_singleton_map(indoc::indoc! {r#" | |
| - image: | |
| productVersion: 3.4.0 | |
| pullPolicy: IfNotPresent | |
| clusterOperation: | |
| reconciliationPaused: false | |
| stopped: false | |
| clusterConfig: | |
| keystore: | |
| - key: s3.client.default.access_key | |
| secretKeyRef: | |
| name: s3-credentials | |
| key: ACCESS_KEY | |
| - key: s3.client.default.secret_key | |
| secretKeyRef: | |
| name: s3-credentials | |
| key: SECRET_KEY | |
| security: | |
| enabled: true | |
| managingRoleGroup: security-coord | |
| settings: | |
| config: | |
| managedBy: operator | |
| content: | |
| value: | |
| _meta: | |
| type: config | |
| config_version: 2 | |
| config: | |
| dynamic: | |
| authc: | |
| basic_internal_auth_domain: | |
| description: Authenticate via HTTP Basic against internal users database | |
| http_enabled: true | |
| transport_enabled: true | |
| order: 1 | |
| http_authenticator: | |
| type: basic | |
| challenge: true | |
| authentication_backend: | |
| type: intern | |
| authz: {} | |
| internalUsers: | |
| managedBy: API | |
| content: | |
| valueFrom: | |
| secretKeyRef: | |
| name: opensearch-security-config | |
| key: internal_users.yml | |
| roles: | |
| managedBy: API | |
| content: | |
| valueFrom: | |
| configMapKeyRef: | |
| name: opensearch-security-config | |
| key: roles.yml | |
| rolesMapping: | |
| managedBy: API | |
| content: | |
| value: | |
| _meta: | |
| type: rolesmapping | |
| config_version: 2 | |
| all_access: | |
| reserved: false | |
| backend_roles: | |
| - admin | |
| tls: | |
| serverSecretClass: tls | |
| internalSecretClass: tls | |
| vectorAggregatorConfigMapName: vector-aggregator-discovery | |
| nodes: | |
| config: | |
| logging: | |
| enableVectorAgent: true | |
| gracefulShutdownTimeout: 2m | |
| requestedSecretLifetime: 1d | |
| envOverrides: | |
| DISABLE_INSTALL_DEMO_CONFIG: "true" | |
| OPENSEARCH_HOME: /stackable/opensearch | |
| configOverrides: | |
| opensearch.yml: | |
| jsonMergePatch: | |
| node.store.allow_mmap: false | |
| cluster.routing.allocation.disk.threshold_enabled: false | |
| roleConfig: | |
| discoveryServiceListenerClass: external-unstable | |
| roleGroups: | |
| cluster-manager: | |
| config: | |
| discoveryServiceExposed: true | |
| nodeRoles: | |
| - cluster_manager | |
| resources: | |
| storage: | |
| data: | |
| capacity: 100Mi | |
| replicas: 3 | |
| data: | |
| config: | |
| discoveryServiceExposed: false | |
| nodeRoles: | |
| - ingest | |
| - data | |
| - remote_cluster_client | |
| listenerClass: cluster-internal | |
| resources: | |
| storage: | |
| data: | |
| capacity: 2Gi | |
| configOverrides: | |
| opensearch.yml: | |
| jsonMergePatch: | |
| node.attr.zone: eu-central-1a | |
| envOverrides: | |
| OPENSEARCH_JAVA_OPTS: -Xms1g -Xmx1g | |
| replicas: 2 | |
| - image: | |
| custom: oci.example.com/namespace/opensearch:3.4.0-custom | |
| productVersion: 3.4.0 | |
| pullPolicy: Always | |
| pullSecrets: | |
| - name: registry-credentials | |
| clusterConfig: | |
| tls: | |
| serverSecretClass: null | |
| security: | |
| enabled: false | |
| nodes: | |
| roleGroups: | |
| default: | |
| replicas: 1 | |
| "#}) | |
| .expect("Failed to parse OpenSearchClusterSpec YAML") | |
| serde_json::from_value(json!([ | |
| { | |
| "image": { | |
| "productVersion": "3.4.0", | |
| "pullPolicy": "IfNotPresent" | |
| }, | |
| "clusterOperation": { | |
| "reconciliationPaused": false, | |
| "stopped": false | |
| }, | |
| "clusterConfig": { | |
| "keystore": [ | |
| { | |
| "key": "s3.client.default.access_key", | |
| "secretKeyRef": { | |
| "name": "s3-credentials", | |
| "key": "ACCESS_KEY" | |
| } | |
| }, | |
| { | |
| "key": "s3.client.default.secret_key", | |
| "secretKeyRef": { | |
| "name": "s3-credentials", | |
| "key": "SECRET_KEY" | |
| } | |
| } | |
| ], | |
| "security": { | |
| "enabled": true, | |
| "managingRoleGroup": "security-coord", | |
| "settings": { | |
| "config": { | |
| "managedBy": "operator", | |
| "content": { | |
| "value": { | |
| "_meta": { | |
| "type": "config", | |
| "config_version": 2 | |
| }, | |
| "config": { | |
| "dynamic": { | |
| "authc": { | |
| "basic_internal_auth_domain": { | |
| "description": "Authenticate via HTTP Basic against internal users database", | |
| "http_enabled": true, | |
| "transport_enabled": true, | |
| "order": 1, | |
| "http_authenticator": { | |
| "type": "basic", | |
| "challenge": true | |
| }, | |
| "authentication_backend": { | |
| "type": "intern" | |
| } | |
| } | |
| }, | |
| "authz": {} | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "internalUsers": { | |
| "managedBy": "API", | |
| "content": { | |
| "valueFrom": { | |
| "secretKeyRef": { | |
| "name": "opensearch-security-config", | |
| "key": "internal_users.yml" | |
| } | |
| } | |
| } | |
| }, | |
| "roles": { | |
| "managedBy": "API", | |
| "content": { | |
| "valueFrom": { | |
| "configMapKeyRef": { | |
| "name": "opensearch-security-config", | |
| "key": "roles.yml" | |
| } | |
| } | |
| } | |
| }, | |
| "rolesMapping": { | |
| "managedBy": "API", | |
| "content": { | |
| "value": { | |
| "_meta": { | |
| "type": "rolesmapping", | |
| "config_version": 2 | |
| }, | |
| "all_access": { | |
| "reserved": false, | |
| "backend_roles": ["admin"] | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| "tls": { | |
| "serverSecretClass": "tls", | |
| "internalSecretClass": "tls" | |
| }, | |
| "vectorAggregatorConfigMapName": "vector-aggregator-discovery" | |
| }, | |
| "nodes": { | |
| "config": { | |
| "logging": { | |
| "enableVectorAgent": true | |
| }, | |
| "gracefulShutdownTimeout": "2m", | |
| "requestedSecretLifetime": "1d" | |
| }, | |
| "envOverrides": { | |
| "DISABLE_INSTALL_DEMO_CONFIG": "true", | |
| "OPENSEARCH_HOME": "/stackable/opensearch" | |
| }, | |
| "configOverrides": { | |
| "opensearch.yml": { | |
| "jsonMergePatch": { | |
| "node.store.allow_mmap": false, | |
| "cluster.routing.allocation.disk.threshold_enabled": false | |
| } | |
| } | |
| }, | |
| "roleConfig": { | |
| "discoveryServiceListenerClass": "external-unstable" | |
| }, | |
| "roleGroups": { | |
| "cluster-manager": { | |
| "config": { | |
| "discoveryServiceExposed": true, | |
| "nodeRoles": ["cluster_manager"], | |
| "resources": { | |
| "storage": { | |
| "data": { | |
| "capacity": "100Mi" | |
| } | |
| } | |
| } | |
| }, | |
| "replicas": 3 | |
| }, | |
| "data": { | |
| "config": { | |
| "discoveryServiceExposed": false, | |
| "nodeRoles": ["ingest", "data", "remote_cluster_client"], | |
| "listenerClass": "cluster-internal", | |
| "resources": { | |
| "storage": { | |
| "data": { | |
| "capacity": "2Gi" | |
| } | |
| } | |
| } | |
| }, | |
| "configOverrides": { | |
| "opensearch.yml": { | |
| "jsonMergePatch": { | |
| "node.attr.zone": "eu-central-1a" | |
| } | |
| } | |
| }, | |
| "envOverrides": { | |
| "OPENSEARCH_JAVA_OPTS": "-Xms1g -Xmx1g" | |
| }, | |
| "replicas": 2 | |
| } | |
| } | |
| } | |
| }, | |
| { | |
| "image": { | |
| "custom": "oci.example.com/namespace/opensearch:3.4.0-custom", | |
| "productVersion": "3.4.0", | |
| "pullPolicy": "Always", | |
| "pullSecrets": [ | |
| { | |
| "name": "registry-credentials" | |
| } | |
| ] | |
| }, | |
| "clusterConfig": { | |
| "tls": { | |
| "serverSecretClass": null | |
| }, | |
| "security": { | |
| "enabled": false | |
| } | |
| }, | |
| "nodes": { | |
| "roleGroups": { | |
| "default": { | |
| "replicas": 1 | |
| } | |
| } | |
| } | |
| } | |
| ])).expect("should be deserializable as an array of OpenSearchClusterSpecs") |
Alternatively, the YAML file could be stored outside the code and included with include_str!.
There was a problem hiding this comment.
Having it as YAML has the benefit you can copy/paste parts from many different kuttl tests or getting started guides into this YAML.
It's "your" operator, I let you decide. From my perspective feel free to push any preferred variant to this PR directly.
However, I was annoyed by include_str indirection in the past - for this big YAML it's absolutely fine, but it would be inconsistent if we only do that here
Part of stackabletech/issues#716